<?

namespace core;
use function Swoole\Coroutine\run;

class Bin 
{

    public static function load()
    {
        if (!is_dir(BASE_PATH.'/runtime')) {
            mkdir(BASE_PATH.'/runtime',777,true);
        }

        spl_autoload_register(function ($class) {

            $file = BASE_PATH . '/' . str_replace('\\', '/', $class) . '.php';
            $file.PHP_EOL;
            if (is_file($file)) {
                // loger($class);
                include_once $file;
            }
        }, true, true);

        //导入env配置
        if (is_file(BASE_PATH.'/.env')) {
            $o = parse_ini_file(BASE_PATH.'/.env');
            foreach ($o as $k => $v) {
                putenv($k.'='.$v);
            }
        }

        //导入配置文件
        self::pf(BASE_PATH.'/app/config',fn($f)=>$GLOBALS['config'][preg_replace('/.+\/|.php/', '', $f)]=include_once $f);
        //导入测试文件
        self::pf(BASE_PATH.'/app/test',fn($f)=>include_once $f);

    }

    public static function loadApi()
    {
        self::pf(BASE_PATH.'/app/api',function($f){
            
            $apiName = preg_replace('/.+\/|.php/', '', $f);
            $class   = str_replace('/', '\\', 'app/api/' . $apiName);
            $obj     = new \ReflectionClass($class);
            $GLOBALS['config']['interface'][$apiName] = new $class();
            $attrName = $obj->getNamespaceName() . '\\Attr';
            foreach ($obj->getMethods() as $k => $v) {
                $method = $v->name;
                if ($type = $v->getAttributes($attrName)[0] ?? null) {
                    $tmp=[
                        'controller'=>$apiName ,
                        'method'=>$method,
                        'name'=>'',
                        'uri'=>strtolower($apiName ). '/' . $method,
                        'auth'=>'login',
                    ];
                    $tmp = array_merge($tmp,$type->getArguments());
                    $GLOBALS['config']['router'][$tmp['uri']] = $tmp;
                }
            }
        });

        // loger($GLOBALS['config']);
    }

    public static function loadTasker()
    {
        self::pf(BASE_PATH.'/app/tasker',function($f){
            
            $tasker = preg_replace('/.+\/|.php/', '', $f);
            $class   = str_replace('/', '\\', 'app/task/' . $tasker);
            $obj     = new \ReflectionClass($class);
            $GLOBALS['config']['tasker'][$tasker] = new $class();
            $attrName = $obj->getNamespaceName() . '\\Attr';
            foreach ($obj->getMethods() as $k => $v) {
                $method = $v->name;
                if ($type = $v->getAttributes($attrName)[0] ?? null) {
                    loger($type->getArguments());
                    // $tmp=[
                    //     'controller'=>$tasker ,
                    //     'method'=>$method,
                    //     'name'=>'',
                    //     'uri'=>strtolower($tasker ). '/' . $method,
                    //     'auth'=>'login',
                    // ];
                    // $tmp = array_merge($tmp,$type->getArguments());
                    // $GLOBALS['config']['router'][$tmp['uri']] = $tmp;
                }
            }
        });

        // loger('loadApi');
    }


    public static function cmd($opt)
    {
        


        
        $e   = array_shift($opt);
        $cmd = array_shift($opt);
 
        switch ($cmd) {
            case 'start':
                self::load();
                self::loadApi();
                require_once BASE_PATH . '/core/Srv.php';
                Srv::start();
                break;
            case 'reload':
                break;
            case 'stop':
 
                break;
            case 'fn': //函数|方法
                self::load();
                run(function () use ($opt) {
                    try {
                        $handler = array_shift($opt);
                        $handler(...$opt);
                    } catch (\Throwable $e) {
                        loger($e);
                    }
                });
                break;
            case 'fc':
                self::load();
                try {
                    $handler = array_shift($opt);
                    $handler(...$opt);
                } catch (\Throwable $e) {
                    loger($e);
                }
                break;
            case 'task': //任务
                self::load();
                run(function () use ($opt) {
                    try {
                        $handler        = array_shift($opt);
                        [$obj, $method] = explode(':', $handler);
                        $class          = implode('\\', ['app', 'task', $obj]);
                        (new $class)->$method(...$opt);
                    } catch (\Throwable $e) {
                        loger($e);
                    }
                });
                break;
            case 'push':
                if ($opt) {
                    echo shell_exec('sudo git add . && sudo git commit -m '.time().' && sudo git push');
                } else {
                    echo shell_exec('git add . && git commit -m '.time().' && git push');
                }
                
                break;
            case 'pull':
                echo shell_exec('git pull');
                break;
            case 'init':
                
                break;
            default:
                loger($cmd);
                break;
        }

    }

    /**
     * pathFiles
     *
     * @param      string  $path   The path
     * @param      bool    $call   The call
     * @param      array   $files  The files
     *
     * @return     array   ( description_of_the_return_value )
     */
    public static function pf($path='', $call = null,&$files=[])
    {

        if (is_dir($path)) {
            //是否为目录
            $dp = dir($path);
            while ($file = $dp->read()) {
                if ($file != "." && $file != "..") {
                    self::pf($path . "/" . $file, $call,$files); //递归
                }
            }
            $dp->close();
        }
        
        if (is_file($path)) {
            $call?$call($path):array_push($files, $path);
        }

        return $files??[];
    }

}